import os
from pathlib import Path
import shutil
import time
from config import Config
from logger import Logger
from ssh_target import SSHTarget
from repo import Repo
import sys
import select
import threading
import keyboard


class Syncer:
    def __init__(self, config_file):
        self.config = Config(config_file)
        self.repo = Repo(
            self.config.repo_uri,
            self.config.get_local_repo_path(),
            self.config.backup_dir,
        )
        self.ssh_target = None
        if self.config.dest_dir.startswith("ssh://"):
            self.ssh_target = SSHTarget(self.config.dest_dir, self.config.ssh_key)
        elif (
            ":" in self.config.dest_dir
            and "@" in self.config.dest_dir
            and self.config.dest_dir.count(":") == 1
        ):
            self.ssh_target = SSHTarget(self.config.dest_dir, self.config.ssh_key)

        self.running = False

    def copy_files_local(self, source_path, dest_path):
        """Copy files from source to local destination"""
        Logger.info(f"Copying files from {source_path} to {dest_path}...")

        # Create destination directory if it doesn't exist
        os.makedirs(dest_path, exist_ok=True)

        # Copy all files and directories
        if os.path.exists(source_path):
            for item in os.listdir(source_path):
                source_item = os.path.join(source_path, item)
                dest_item = os.path.join(dest_path, item)

                if os.path.isdir(source_item):
                    try:
                        shutil.copytree(source_item, dest_item, dirs_exist_ok=True)
                    except Exception as e:
                        Logger.warning(f"Failed to copy directory {source_item}: {e}")
                else:
                    try:
                        shutil.copy2(source_item, dest_item)
                    except Exception as e:
                        Logger.warning(f"Failed to copy file {source_item}: {e}")
            Logger.success("Files copied successfully.")
        else:
            Logger.error(f"Source directory does not exist: {source_path}")
            raise FileNotFoundError(f"Source directory does not exist: {source_path}")

    # def _check_keypress():
    #     Logger.info("Press ESC to exit")
    #     keyboard.wait("esc")
    #     sys.exit()
    def start(self):
        self.running = True
        first_run = True

        # threading.Thread(target=self._check_keypress, daemon=True).start()
        if self.ssh_target:
            self.ssh_target.connect()
            self.ssh_target.create_remote_dirs()

        while self.running:
            self.one_time_sync(first_run)
            first_run = False
            if self.config.refresh_interval > 0:
                Logger.info(
                    f"Waiting {self.config.refresh_interval} seconds before next update check..."
                )
                time.sleep(self.config.refresh_interval)
            else:
                self.running = False
        self.ssh_target.close()

    def one_time_sync(self, force_sync: bool = False):
        Logger.begin_section("Sync")
        need_sync = self.repo.update()
        if force_sync or need_sync:
            Logger.info("Updates detected, starting copy operations...")
            if self.ssh_target:
                self.ssh_target.copy_files(self.config.get_source_path())
            else:
                self.copy_files_local(
                    self.config.get_source_path(), self.config.dest_dir
                )
        Logger.end_section()


if __name__ == "__main__":
    Syncer(".config.json").start()
